/*  */
#include "cstdlib.h"

#include "interpreter.h"
#include "table.h"
#include "type.h"

void Cstdlib::StdAsctime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = asctime((const tm *)param[0]->val->pointer);
}

void Cstdlib::StdClock(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = clock();
}

void Cstdlib::StdCtime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = ctime((const time_t *)param[0]->val->pointer);
}

void Cstdlib::StdDifftime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->fP = difftime((time_t)param[0]->val->integer,
        param[1]->val->integer);
}

void Cstdlib::StdGmtime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = gmtime((const time_t *)param[0]->val->pointer);
}

void Cstdlib::StdLocaltime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = localtime((const time_t *)param[0]->val->pointer);
}

void Cstdlib::StdMktime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = (int)mktime((tm *)param[0]->val->pointer);
}

void Cstdlib::StdTime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = (int)time((time_t *)param[0]->val->pointer);
}

void Cstdlib::StdStrftime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strftime((char *)param[0]->val->pointer,
        param[1]->val->integer, (const char *)param[2]->val->pointer, (const tm *)param[3]->val->pointer);
}

#ifndef WIN32
void Cstdlib::StdStrptime(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
	  extern char *strptime(const char *s, const char *format, struct tm *tm);

    returnValue->val->pointer = strptime(param[0]->val->pointer,
        param[1]->val->pointer, param[2]->val->pointer);
}

void Cstdlib::StdGmtime_r(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = (void*)gmtime_r(param[0]->val->pointer,
        param[1]->val->pointer);
}

void Cstdlib::StdTimegm(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = timegm(param[0]->val->pointer);
}
#endif

/* handy structure definitions */
const char Cstdlib::kStdTimeDefs[] = "\
typedef int time_t; \
typedef int clock_t;\
";

/* all string.h functions */
const LibraryFunction Cstdlib::StdTimeFunctions[] =
{
    {Cstdlib::StdAsctime, "char *asctime(struct tm *);"},
    {Cstdlib::StdClock, "time_t clock();"},
    {Cstdlib::StdCtime, "char *ctime(int *);"},
    {Cstdlib::StdDifftime, "double difftime(int, int);"},
    {Cstdlib::StdGmtime, "struct tm *gmtime(int *);"},
    {Cstdlib::StdLocaltime, "struct tm *localtime(int *);"},
    {Cstdlib::StdMktime, "int mktime(struct tm *ptm);"},
    {Cstdlib::StdTime, "int time(int *);"},
    {Cstdlib::StdStrftime, "int strftime(char *, int, char *, struct tm *);"},
#ifndef WIN32
    {Cstdlib::StdStrptime, "char *strptime(char *, char *, struct tm *);"},
	{Cstdlib::StdGmtime_r, "struct tm *gmtime_r(int *, struct tm *);"},
    {Cstdlib::StdTimegm, "int timegm(struct tm *);"},
#endif
    {NULL, NULL}
};


/* creates various system-dependent definitions */
void Cstdlib::StdTimeSetupFunc(Interpreter *pc)
{
    /* make a "struct tm" which is the same size as a native tm structure */
    Type::TypeCreateOpaqueStruct(pc, NULL, MyTable::TableStrRegister(pc, "tm"),
        sizeof(struct tm));

    /* define CLK_PER_SEC etc. */
    (pc, NULL, "CLOCKS_PER_SEC", &pc->intType,
        (AnyValue*)&CLOCKS_PER_SECValue, false);
#ifdef CLK_PER_SEC
    (pc, NULL, "CLK_PER_SEC", &pc->intType,
        (AnyValue*)&CLK_PER_SECValue, false);
#endif
#ifdef CLK_TCK
    (pc, NULL, "CLK_TCK", &pc->intType,
        (AnyValue*)&CLK_TCKValue, false);
#endif
}

